//命令行输入--读取灰度图像数据A--领域均值法求矩阵B--转化位二值图像--保存文件，以bmp文件格式
//领域均值法：遍历--确定领域范围--超出部分用0代替
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"bmp.h"
int main(int argc,char* argv[] )
{
    if(argc!=5)
    {
        printf("The number of argvs is false.");
        return 1;
    }
    

    //打开文件
    FILE* fp=fopen(argv[1],"rb");
    if(fp==NULL)
    {
        printf("open file error!\n");
        return 1;
    }
    //创建目标文件
    FILE* fresult=fopen(argv[2],"wb");
    if(fresult==NULL)
    {
        printf("create file error!\n");
        fclose(fp);
        return 1;
    }
//------------------------------------------------------------------//
    //声明结构体变量
    BITMAPFILEHEADER bfh;//源文件
    BITMAPINFOHEADER bih;
    RGBQUAD pal[256];//调色板只要两个颜色就够了

    //读取图像头信息保存到变量里
    fread(&bfh,sizeof(BITMAPFILEHEADER),1,fp);
    fread(&bih,sizeof(BITMAPINFOHEADER),1,fp);
    fread(pal,sizeof(RGBQUAD),256,fp);
    
    int widthbytes=(bih.biWidth+3)/4*4; //每行字节数必须是4的倍数
    //分配内存
    unsigned char *pbits=(unsigned char *)malloc(widthbytes*bih.biHeight);//源图像信息
    unsigned char *pbits2=(unsigned char *)malloc(widthbytes*bih.biHeight);//目标图像信息
    if(pbits==NULL||pbits2==NULL)
    {
        printf("malloc error!\n");
        free(pbits);
        free(pbits2);
        fclose(fp);
        fclose(fresult);
        return 1;
    }
    //读取位图数据
    fread(pbits,1, widthbytes*bih.biHeight,fp);//读取所有位图信息
    
    //修改文件头信息
    //bfh.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+2*sizeof(RGBQUAD);//数据区偏移量，等于文件头，信息头，索引表的大小之和
    //bfh.bfSize=bfh.bfOffBits+bih.biSizeImage;//文件大小，等于偏移量加上数据区大小
    //修改信息头
    //bih.biBitCount=8;//改彩色为灰度
    //bih.biSizeImage=widthbytes*bih.biHeight;//像素信息大小
    //bih.biClrUsed=2;//颜色索引表数量为黑白
    //bih.biClrImportant=2;//重要颜色索引表数量为黑白,都重要
    //修改调色板为黑白
    pal[0].rgbBlue=pal[0].rgbGreen=pal[0].rgbRed=pal[0].rgbReserved=0;//调色板颜色为黑色对应的索引为0
    pal[255].rgbBlue=pal[255].rgbGreen=pal[255].rgbRed=255;//白色对应的索引为150-255
    pal[255].rgbReserved=0;

    //把头信息写入目标文件
    fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fresult);
    fwrite(&bih,sizeof(BITMAPINFOHEADER),1,fresult);
    fwrite(pal,sizeof(RGBQUAD),256,fresult);

    //------------------------------------------------------------------//
    //检查命令行参数
    if(strncmp(argv[3],"-r=",3)!=0||strncmp(argv[4],"-t=",3)!=0)
    {
        printf("argvs are not valid.");
        free(pbits);
        free(pbits2);   
        fclose(fp);
        fclose(fresult);
        return 1;
    }
    int r=atoi(argv[3]+3);//邻域范围
    int t=atoi(argv[4]+3);//阈值
    //修改位图数据
    for(int i=0;i<bih.biHeight;i++)
    {
        for(int j=0;j<bih.biWidth;j++)
        {
            int sum=0;//像素值和
            int count=0;//像素个数
            //遍历邻域
            for(int k=i-r;k<=i+r;k++)
            {
                for(int l=j-r;l<=j+r;l++)
                {
                    if(k>=0&&k<bih.biHeight&&l>=0&&l<bih.biWidth)//没有越界
                    {
                        sum+=pbits[k*widthbytes+l];
                        count++;
                    }
                }
            }
            //计算平均值并二值化
            int avg=sum/count;
            if(avg<t)
            {
                pbits2[i*widthbytes+j]=0;//小于阈值，置为黑色
            }
            else
            {
                pbits2[i*widthbytes+j]=255;//大于阈值，置为白色
            }
        }
    }
    //保存位图数据到目标文件
    fwrite(pbits2,widthbytes*bih.biHeight,1,fresult);

    //释放 关闭
    free(pbits);
    free(pbits2);
    fclose(fresult);
    fclose(fp);
    return 0;
}